import 'dart:async';
import 'dart:convert';

import 'package:flutter/services.dart';

class FlutterPush {
  static const MethodChannel _channel = const MethodChannel('flutter_push');

  /// 用于发射打开推送通知数据的流控制器
  static final _openNotificationStreamController = StreamController<Map<String, dynamic>>();

  /// 用于发射接收到推送通知数据的流控制器
  static final _receiveNotificationStreamController = StreamController<Map<String, dynamic>>.broadcast();

  /// 用于发射接收到透传消息数据的流控制器
  static final _receiveMessageStreamController = StreamController<CPushMessage>();

  /// 初始化插件
  static void init() {
    _channel.setMethodCallHandler(_handler);
  }

  /// 注册推送服务
  ///
  /// [accountId]当前账户id，返回注册token（暂不使用）
  static Future<String> registerPushService(String accountId) async {
    final String token = await _channel.invokeMethod("registerPushService", {"accountId": accountId});

    return token;
  }

  /// 注销推送服务
  static unregisterPushService() {
    return _channel.invokeMethod("unregisterPushService");
  }

  /// 打开推送通知事件流
  static final Stream<Map<String, dynamic>> openNotificationStream =
      _openNotificationStreamController.stream.asBroadcastStream(
    onListen: (subscription) => subscription.resume(),
    onCancel: (subscription) => subscription.pause(),
  );

  /// 接收到推送通知事件流
  static Stream<Map<String, dynamic>> get receiveNotificationStream => _receiveNotificationStreamController.stream;

  /// 接收到透传消息事件流
  static final Stream<CPushMessage> receiveMessageStream = _receiveMessageStreamController.stream.asBroadcastStream(
    onListen: (subscription) => subscription.resume(),
    onCancel: (subscription) => subscription.pause(),
  );

  /// 通道事件处理器
  static Future<dynamic> _handler(MethodCall call) async {
    switch (call.method) {
      case 'openNotification':
        _openNotificationStreamController.add(jsonDecode(call.arguments ?? '{}'));
        break;
      case 'receiveNotification':
        _receiveNotificationStreamController.add(jsonDecode(call.arguments ?? '{}'));
        break;
      case 'receiveMessage':
        _receiveMessageStreamController.add(CPushMessage(
          id: call.arguments['id'],
          title: call.arguments['title'],
          content: call.arguments['content'],
        ));
        break;
    }
  }
}

/// 透传消息数据结构
class CPushMessage {
  /// 消息id
  final String id;

  /// 消息标题
  final String title;

  /// 消息内容
  final String content;

  CPushMessage({this.id, this.title, this.content});
}
